/******************************************************************/
/* 				MOLPROC.H						*/
/******************************************************************/

#define BITCHUNK_BITS   (sizeof(bitchunk_t) * CHAR_BIT)
#define BITMAP_CHUNKS(nr_bits) (((nr_bits)+BITCHUNK_BITS-1)/BITCHUNK_BITS)  

typedef unsigned long irq_id_t;	
typedef unsigned reg_t;		/* machine register */
typedef unsigned short bitchunk_t; /* collection of bits in a bitmap */

/* Process table and system property related types. */ 
typedef short sys_id_t;			/* system process index */
typedef struct {			/* bitmap for system indexes */
  bitchunk_t chunk[BITMAP_CHUNKS(NR_SYS_PROCS)];
} sys_map_t;

typedef unsigned long phys_bytes;	/* physical addr/length in bytes */

/* Max. number of I/O ranges that can be assigned to a process */
#define NR_IO_RANGE	10

/* Max. number of device memory ranges that can be assigned to a process */
#define NR_MEM_RANGE	10

/* Max. number of IRQs that can be assigned to a process */
#define NR_IRQ	4

/* Magic system structure table addresses. */
#define BEG_PRIV_ADDR (&priv[0])
#define END_PRIV_ADDR (&priv[NR_SYS_PROCS])

struct io_range
{
	unsigned ior_base;	/* Lowest I/O port in range */
	unsigned ior_limit;	/* Highest I/O port in range */
};

struct mem_range
{
	phys_bytes mr_base;	/* Lowest memory address in range */
	phys_bytes mr_limit;	/* Highest memory address in range */
};


/*----------------------------------------------------------------------*/
/* PSEUDO KERNEL PRIV STRUCTURE			*/
/*----------------------------------------------------------------------*/
struct priv {
  proc_nr_t s_proc_nr;		/* number of associated process */
  sys_id_t s_id;		/* index of this system structure */
  short s_flags;		/* PREEMTIBLE, BILLABLE, etc. */

  short s_trap_mask;		/* allowed system call traps */
  sys_map_t s_ipc_from;		/* allowed callers to receive from */
  sys_map_t s_ipc_to;		/* allowed destination processes */
  long s_call_mask;		/* allowed kernel calls */

  sys_map_t s_notify_pending;  	/* bit map with pending notifications */
  irq_id_t s_int_pending;	/* pending hardware interrupts */
  sigset_t s_sig_pending;	/* pending signals */

  timer_t s_alarm_timer;	/* synchronous alarm timer */ 
  reg_t *s_stack_guard;		/* stack guard word for kernel tasks */

  int s_nr_io_range;		/* allowed I/O ports */
  struct io_range s_io_tab[NR_IO_RANGE];

  int s_nr_mem_range;		/* allowed memory ranges */
  struct mem_range s_mem_tab[NR_MEM_RANGE];

  int s_nr_irq;			/* allowed IRQ lines */
  int s_irq_tab[NR_IRQ];
};

/*----------------------------------------------------------------------*/
/* PSEUDO KERNEL PROC STRUCTURE							*/
/*----------------------------------------------------------------------*/
struct kproc {
  pid_t	pid;			/* LINUX pid 					*/
  int		nid;			/* Process NODE ID				*/
  
  struct sockaddr ipc_addr;		/* LINUX process  IPC socket address	*/
  struct sockaddr ctrl_addr;	/* LINUX process CTRL socket address 	*/

  unsigned long kseq;		/* KMINIXD message sequence #		*/
  unsigned long pseq;		/* process message sequence #		*/

  unsigned int  p_hello;		/* When ticks = 0 the HELLO test is enable for this process 	*/
  unsigned int  p_dead;		/* # of HELLO message without responde 	*/

  proc_nr_t p_nr;			/* number of this process (for fast access) */
  struct priv *p_priv;		/* system privileges structure */
  short p_rts_flags;		/* process is runnable only if zero */
  short p_misc_flags;		/* flags that do suspend the process */

  char p_priority;		/* current scheduling priority */
  char p_max_priority;		/* maximum scheduling priority */
  char p_ticks_left;		/* number of scheduling ticks left */
  char p_quantum_size;		/* quantum size in ticks */

  clock_t p_user_time;		/* user time in ticks */
  clock_t p_sys_time;		/* sys time in ticks */

  struct kproc *p_nextready;	/* pointer to next ready process */
  struct kproc *p_caller_q;	/* head of list of procs wishing to send */
  struct kproc *p_q_link;	/* link to next proc wishing to send */

  message messbuf;		/* message buffer */

  int p_getfrom_e;		/* from whom does process want to receive? */
  int p_sendto_e;			/* to whom does process want to send? */
  sigset_t p_pending;		/* bit map for pending kernel signals */
  char p_name[P_NAME_LEN];	/* name of the process, including \0 */
  int p_endpoint;			/* endpoint number, generation-aware */
} ; 
 
#define NIL_PROC          ((struct kproc *) 0)		
#define NIL_SYS_PROC      ((struct kproc *) 1)

struct name2nr_s {
  proc_nr_t proc_nr;			/* process number to use */
  char proc_name[P_NAME_LEN];		/* name in process table */
};

typedef struct name2nr_s name2nr_t;


_PROTOTYPE(int mol_mini_send, 	(ipc_t *pipc));
_PROTOTYPE(int mol_mini_receive, 	(ipc_t *pipc));
_PROTOTYPE(int mol_mini_sendrec,	(ipc_t *pipc));
_PROTOTYPE(int mol_mini_notify,	(ipc_t *pipc));

/*---------------------- LOCAL FUNCTIONS -------------------------*/
_PROTOTYPE(proc_nr_t check_endpoint,(int endpoint));
_PROTOTYPE(int check_notready,(struct kproc *ptr, ipc_t *pipc));
_PROTOTYPE(int check_sameproc,(struct kproc *ptr, ipc_t *pipc));
_PROTOTYPE(int check_sequence,(struct kproc *ptr, ipc_t *pipc));
_PROTOTYPE(int check_registered,(struct kproc *ptr, ipc_t *pipc));





